import 'dart:async';

import 'package:bike_ride/common/util/hysize_fit.dart';
import 'package:bike_ride/common/util/regex.dart';
import 'package:bike_ride/model/login/view/login_protocol_v.dart';
import 'package:bike_ride/model/login/view_model/login_vm.dart';
import 'package:bike_ride/generated/l10n.dart';
import 'package:bike_ride/res/style/color_styles.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';

class PhoneTypeWidget extends StatefulWidget {
  final LoginViewModel viewModel;
  final Function onSuccess;
  final bool isAgreePrivacy;

  const PhoneTypeWidget(
      {super.key,
        required this.viewModel, required this.onSuccess, required this.isAgreePrivacy,});

  @override
  State<PhoneTypeWidget> createState() => _PhoneTypeWidgetState();
}

class _PhoneTypeWidgetState extends State<PhoneTypeWidget> {
  final _mobileController = TextEditingController();
  final _smsController = TextEditingController();
  final FocusNode _usernameFocusNode = FocusNode();
  final FocusNode _smsFocusNode = FocusNode();

  /// 发送验证码按钮可用
  final _allowRequestOtpNotifier = ValueNotifier(false);
  final _mobileCanClearNotifier = ValueNotifier(false);

  /// 登录按钮
  final _loginEditDataNotifier = ValueNotifier<String>('');
  final _isAgreePrivacy = ValueNotifier<bool>(false);

  bool _isSending = false; // 防止重复发送验证码
  bool _isLoggingIn = false; // 防止重复登录

  Future<void> sendOpt() async {
    if (_isSending) return;
    _isSending = true;

    try {
      /*if (isValidTel(_loginEditDataNotifier.value)) {
        await widget.viewModel.mobileSendCode(mobile: _loginEditDataNotifier.value);
      } else */if (isEmail(_loginEditDataNotifier.value)) {
        await widget.viewModel.emailSendCode(email: _loginEditDataNotifier.value);
      } else {
        EasyLoading.showError(_mobileController.text.isEmpty
            ? S.current.editMobileOrEmail
            : S.current.editMobileOrEmailValid);
      }
    } catch (e) {
      EasyLoading.showError(e.toString());
    } finally {
      _isSending = false;
    }
  }

  Future<void> login() async {
    if (_isLoggingIn) return;
    _isLoggingIn = true;

    try {
      if (_smsController.text.isEmpty) {
        EasyLoading.showError(S.current.editValidCode);
        return;
      }

      if(!_isAgreePrivacy.value){
        EasyLoading.showError(S.current.editValidProtocol);
        return;
      }

      /*if (isValidTel(_loginEditDataNotifier.value)) {
        EasyLoading.show();
        final success = await widget.viewModel.mobileLogin(mobile: _loginEditDataNotifier.value, code: _smsController.text);
        if (success) {
          EasyLoading.dismiss();
          widget.onSuccess();
        }
      } else */if (isEmail(_loginEditDataNotifier.value)) {
        EasyLoading.show();
        final success = await widget.viewModel.emailLogin(email: _loginEditDataNotifier.value, code: _smsController.text);
        if (success) {
          EasyLoading.dismiss();
          widget.onSuccess();
        }
      } else {
        EasyLoading.showError(_mobileController.text.isEmpty
            ? S.current.editMobileOrEmail
            : S.current.editMobileOrEmailValid);
      }
    } catch (e) {
      EasyLoading.showError(e.toString());
    } finally {
      _isLoggingIn = false;
    }
  }

  @override
  void initState() {
    super.initState();
    _isAgreePrivacy.value = widget.isAgreePrivacy;
    _mobileController.addListener(() {
      final text = _mobileController.text;
      _mobileCanClearNotifier.value = text.isNotEmpty;
      _allowRequestOtpNotifier.value = /*isValidTel(text) || */isEmail(text);
      _loginEditDataNotifier.value = text;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        _TextField(
          controller: _mobileController,
          hintText: S.current.editMobileOrEmail,
          focusNode: _usernameFocusNode,
          autofillHints: const [
            AutofillHints.telephoneNumberDevice,
          ],
          right: AnimatedBuilder(
            animation: _mobileCanClearNotifier,
            builder: (context, _) {
              if (!_mobileCanClearNotifier.value) {
                return const SizedBox();
              }
              return IconButton(
                padding: EdgeInsets.zero,
                splashColor: Colors.transparent,
                alignment: Alignment.centerRight,
                onPressed: () {
                  _mobileController.clear();
                },
                icon: Icon(
                  Icons.clear,
                  size: 38.rpx,
                  color: Colors.black.withAlpha(35),
                ),
              );
            },
          ),
        ),
        SizedBox(
          height: 24.rpx,
        ),
        _TextField(
          controller: _smsController,
          hintText: S.current.editValidCode,
          keyboardType: TextInputType.number,
          focusNode: _smsFocusNode,
          maxLength: 6,
          autofillHints: const [
            AutofillHints.oneTimeCode,
          ],
          right: AnimatedBuilder(
            animation: _allowRequestOtpNotifier,
            builder: (context, _) {
              return SendOtpButton(
                isValidAccount: _allowRequestOtpNotifier.value,
                sendOtp: sendOpt,
              );
            },
          ),
        ),
        SizedBox(
          height: 24.rpx,
        ),
        ValueListenableBuilder(
            valueListenable: _isAgreePrivacy,
            builder: (context, data, _) {
              return ProtocolCheck(
                current: data,
                onChanged: (value) {
                  _isAgreePrivacy.value = value;
                },
              );
            }),
        SizedBox(
          height: 24.rpx,
        ),
        AnimatedBuilder(
            animation: _loginEditDataNotifier,
            builder: (context, _) {
              return GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTap: () async {
                  await login();
                },
                child: Container(
                  height: 88.rpx,
                  margin: EdgeInsets.only(top: 60.rpx),
                  padding: const EdgeInsets.symmetric(vertical: 8),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(Radius.circular(20.rpx)),
                    color: Theme.of(context).colorScheme.primary,
                  ),
                  child: Center(
                    child: Builder(builder: (context) {
                      String text;
                      /*if (isValidTel(_loginEditDataNotifier.value)) {
                        text = S.current.loginPhone;
                      } else */if (isEmail(_loginEditDataNotifier.value)) {
                        text = S.current.loginEmail;
                      } else {
                        text = S.current.loginPhoneAndEmail;
                      }
                      return Text(
                        text,
                        style: TextStyle(fontSize: 32.rpx, color: Colors.white),
                      );
                    }),
                  ),
                ),
              );
            })
      ],
    );
  }
}

/// 获取验证码按钮
class SendOtpButton extends StatefulWidget {
  const SendOtpButton({
    Key? key,
    required this.isValidAccount,
    required this.sendOtp,
    this.coolDownSeconds = 60,
  })  : assert(coolDownSeconds != null),
        super(key: key);

  /// 发送验证码
  final Future<void> Function() sendOtp;

  final int? coolDownSeconds;

  ///手机号或邮箱账号是否有效
  final bool isValidAccount;

  @override
  State<SendOtpButton> createState() => SendOtpButtonState();
}

class SendOtpButtonState extends State<SendOtpButton> {
  Timer? _timer;

  /// 倒计时
  int _countdown = 0;

  bool get _countingDown => _countdown != 0;

  /// 异步任务是否正在运行
  bool _running = false;

  /// 是否可用
  bool enabled = true;

  void notifyChange() {
    if (mounted) {
      setState(() {});
    }
  }

  void _onEnabledChanged({bool updateState = true}) {
    enabled = !_countingDown && !_running && widget.isValidAccount;
    if(updateState) {
      notifyChange();
    }
  }

  @override
  void didUpdateWidget(covariant SendOtpButton oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.isValidAccount != oldWidget.isValidAccount) {
      _onEnabledChanged(updateState: false);
    }
  }

  @override
  void initState() {
    super.initState();
    _onEnabledChanged(updateState: false);
  }

  @override
  void dispose() {
    _timer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return TextButton(
      style: TextButton.styleFrom(
        textStyle: const TextStyle(
          inherit: false,
          fontSize: 16,
        ),
      ),
      onPressed: () async {
        if (enabled) {
          try {
            setState(() {
              _running = true;
            });
            await widget.sendOtp();
            _timer?.cancel();
            _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
              _countdown = Duration(seconds: widget.coolDownSeconds!).inSeconds - timer.tick;
              if (_countdown <= 0) {
                _countdown = 0;
                _timer?.cancel();
              }
              _onEnabledChanged();
            });
          } catch (e) {
            EasyLoading.showError(e.toString());
          } finally {
            setState(() {
              _running = false;
            });
          }
        }else{
          EasyLoading.showError(S.current.editMobileOrEmailValid);
        }
      },
      child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            if (_running)
              const SizedBox(
                width: 16,
                height: 16,
                child: CircularProgressIndicator(
                  strokeWidth: 1,
                ),
              ),
            Builder(builder: (context) {
              return Text(
                _running
                    ? S.current.sending
                    : (_countingDown
                    ? '${_countdown}S'
                    : S.current.queryCode),
                style: TextStyle(
                  color: (enabled || _countdown > 0)
                      ? Theme.of(context).colorScheme.primary
                      : ColorStyles.color_999999,
                ),
              );
            })
          ]),
    );
  }
}

/// 文本输入框
class _TextField extends StatelessWidget {
  const _TextField({
    Key? key,
    this.hintText,
    this.controller,
    this.right,
    this.keyboardType,
    this.maxLength,
    this.autofillHints,
    this.focusNode,
  }) : super(key: key);

  final String? hintText;
  final TextEditingController? controller;
  final Widget? right;
  final TextInputType? keyboardType;
  final int? maxLength;
  final Iterable<String>? autofillHints;
  final FocusNode? focusNode;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Container(
          width: double.maxFinite,
          decoration: const BoxDecoration(
              color: Color(0xfff5f5f5),
              borderRadius: BorderRadius.all(Radius.circular(26))),
          child: TextField(
            focusNode: focusNode,
            controller: controller,
            autofillHints: autofillHints,
            keyboardType: keyboardType,
            maxLength: maxLength ?? 100,
            style: TextStyle(
              color: Colors.black,
              fontSize: 32.rpx,
              height: 1.3,
              fontWeight: FontWeight.w500,
            ),
            decoration: InputDecoration(
              border: InputBorder.none,
              counterText: '',
              hintText: hintText ?? '',
              hintStyle: TextStyle(
                color: Colors.black.withAlpha(35),
                fontSize: 32.rpx,
                height: 1.3,
                fontWeight: FontWeight.w500,
              ),
              contentPadding: EdgeInsets.only(
                left: 48.rpx,
                top: 26.rpx,
                right: 48.rpx,
                bottom: 26.rpx,
              ),
            ),
          ),
        ),
        if (right != null)
          Positioned(
            right: 32.rpx,
            top: 0,
            bottom: 0,
            child: Center(child: right),
          ),
      ],
    );
  }
}
